home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / Libraries / C Internet Config / IC Random Signature ƒ / IC Specific Override.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-11-17  |  9.1 KB  |  356 lines  |  [TEXT/SPM ]

  1. /*
  2.     IC Specific Override.c
  3.     
  4.     This is a C port of the ICSpecificOverride.p file.
  5.     
  6.     History:
  7.         11/17/95 dhn - Started port.
  8. */
  9.  
  10. /*
  11.     Original comment:
  12.     
  13.     Internet Config Specific Overide Component
  14.     
  15.     Routine names have an ICSO prefix for Internet Config Specific Override.
  16.     
  17.     To create an IC override component you need to make a copy of this
  18.     file and fill in the blanks. This is an N stage process:
  19.     
  20.     1. Make a copy of this file.
  21.     2. Change kOurComponentManufacturer to your manufacturer code.
  22.     3. Add any shared globals to the sharedGlobals record.
  23.     4. If you have shared globals then init them in ICSOInitShared.
  24.     5. If the shared globals need cleaning up then clean them ICSOCleanShared.
  25.     6. Add any instance specific globals to globalsRecord.
  26.     7. If you have globals then init them in ICSOInitGlobals.
  27.     8. If the globals need cleaning up then clean them ICSOCleanGlobals.
  28.     9. If you want to add a completely new routine or remove support for one of the built in routines then modify
  29.         ICSOCanDo accordingly.
  30.     10. Modify ICSOWhatToOverride to return the correct ProcPtr for each routine that you override or add.
  31.     11. Write each routine. If you want the component to continue calling through to the captured component for
  32.             this routine then have your routine return delegateThisCallErr.
  33.     12. Smirk at the wonders of Component Manager.
  34.     13. Looking inside ICGenericOverride and frown at the wonders of Component Manager.
  35.     
  36.     Share and Enjoy.
  37.     
  38.     Quinn
  39.     12 Feb 1995
  40. */
  41.  
  42. #include <Components.h>
  43. #include <Folders.h>
  44.  
  45. #include "IC Component API.h"
  46. #include "IC Component Selectors.h"
  47.  
  48. #include "IC Specific Override.h"
  49. #include "IC Generic Override.h"
  50.  
  51. pascal short SneakyRandom(GlobalsHandle globals);
  52. pascal void SafeResolveAlias(FSSpec* fs);
  53. pascal OSErr GetNthTextFile(CInfoPBRec* cpbp,FSSpecPtr sig,short max_count,short* count);
  54. pascal void ChooseRandomSignature(GlobalsHandle globals);
  55. pascal ICError RSCBegin(GlobalsHandle globals,ICPerm perm);
  56. pascal ICError RSCGetPref(GlobalsHandle globals,StringPtr key,ICAttr* attr,Ptr buf,long* size);
  57. pascal ICError RSCSetPref(GlobalsHandle globals,StringPtr key,ICAttr* attr,Ptr buf,long* size);
  58.  
  59. enum {
  60.     uppICSOPrefProcInfo=kPascalStackBased
  61.         | RESULT_SIZE(SIZE_CODE(sizeof(ComponentResult)))
  62.         | STACK_ROUTINE_PARAMETER(1,SIZE_CODE(sizeof(GlobalsHandle)))
  63.         | STACK_ROUTINE_PARAMETER(2,SIZE_CODE(sizeof(StringPtr)))
  64.         | STACK_ROUTINE_PARAMETER(3,SIZE_CODE(sizeof(ICAttr*)))
  65.         | STACK_ROUTINE_PARAMETER(4,SIZE_CODE(sizeof(Ptr)))
  66.         | STACK_ROUTINE_PARAMETER(5,SIZE_CODE(sizeof(long*))),
  67.     uppICSOBeginProcInfo=kPascalStackBased
  68.         | RESULT_SIZE(SIZE_CODE(sizeof(ComponentResult)))
  69.         | STACK_ROUTINE_PARAMETER(1,SIZE_CODE(sizeof(GlobalsHandle)))
  70.         | STACK_ROUTINE_PARAMETER(2,SIZE_CODE(sizeof(ICPerm)))
  71. };
  72.  
  73. pascal ComponentResult ICSOInitShared(GlobalsHandle globals){
  74.     
  75.     return noErr;
  76. }
  77.  
  78. pascal ComponentResult ICSOCleanShared(GlobalsHandle globals){
  79.     
  80.     return noErr;
  81. }
  82.  
  83. pascal ComponentResult ICSOInitGlobals(GlobalsHandle globals){
  84.     ComponentResult err=noErr;
  85.     short refnum,oldrefnum;
  86.     StringHandle strh;
  87.     
  88.     (*globals)->random_seed=TickCount();
  89.     (*globals)->current_signature=(Handle)0;
  90.     (*globals)->default_signature=(Handle)0;
  91.     
  92.     oldrefnum=CurResFile();
  93.     refnum=OpenComponentResFile((Component)(*globals)->self);
  94.     
  95.     if (refnum<=0)
  96.         return resNotFound;
  97.     
  98.     UseResFile(refnum);
  99.     
  100.     strh=GetString(kRandomSigFoldName);
  101.     if (strh==(StringHandle)0)
  102.         err=resNotFound;
  103.     else {
  104.         BlockMoveData(*strh,(*globals)->sig_folder_name,(*strh)[0]+1);
  105.     }
  106.     
  107.     if (err==noErr){
  108.         (*globals)->default_signature=Get1Resource('TEXT',kDefaultSignature);
  109.         if ((*globals)->default_signature==(Handle)0)
  110.             err=resNotFound;
  111.         else
  112.             DetachResource((*globals)->default_signature);
  113.     }
  114.     
  115.     CloseComponentResFile(refnum);
  116.     UseResFile(oldrefnum);
  117.     
  118.     return err;
  119. }
  120.  
  121. pascal ComponentResult ICSOCleanGlobals(GlobalsHandle globals){
  122.     ComponentResult err=noErr;
  123.     
  124.     if ((*globals)->current_signature!=(Handle)0){
  125.         DisposeHandle((*globals)->current_signature);
  126.         (*globals)->current_signature=(Handle)0;
  127.     }
  128.     if ((*globals)->default_signature!=(Handle)0){
  129.         DisposeHandle((*globals)->default_signature);
  130.         (*globals)->default_signature=(Handle)0;
  131.     }
  132.     
  133.     return err;
  134. }
  135.  
  136. pascal ComponentResult ICSOCanDo(GlobalsHandle globals,short selector){
  137.     
  138.     return delegateThisCallErr;
  139. }
  140.  
  141. pascal ComponentFunctionUPP ICSOWhatToOverride(GlobalsHandle globals,short selector){
  142.     ComponentFunctionUPP proc=(ComponentFunctionUPP)0;
  143.     
  144.     if (selector==kICCGetPref)
  145.         proc=BuildNewProc(RSCGetPref,uppICSOPrefProcInfo);
  146.     else if (selector==kICCSetPref)
  147.         proc=BuildNewProc(RSCSetPref,uppICSOPrefProcInfo);
  148.     else if (selector==kICCBegin)
  149.         proc=BuildNewProc(RSCBegin,uppICSOBeginProcInfo);
  150.         
  151.     return proc;
  152. }
  153.  
  154. #include <QuickDraw.h>
  155.  
  156. /*
  157.     Get a random number without disturbing the random sequence in use by the application
  158. */
  159. pascal short SneakyRandom(GlobalsHandle globals){
  160.     short ret,temp;
  161.     QDGlobals* qdp;
  162.     long a5;
  163.     
  164.     a5=SetCurrentA5();
  165.     
  166.     if (a5!=0L){
  167.         // calc the top of the qd globals
  168.         qdp=(QDGlobals*)(a5-(sizeof(QDGlobals)-sizeof(GrafPtr)));
  169.         
  170.         // save and reset the random seed
  171.         temp=qdp->randSeed;
  172.         qdp->randSeed=(*globals)->random_seed;
  173.     }
  174.         
  175.     // get the random number
  176.     ret=Random();
  177.     
  178.     if (a5!=0L){
  179.         // restore the seed before returning
  180.         qdp->randSeed=temp;
  181.     }
  182.     
  183.     if (ret<0)
  184.         return -ret;
  185.     
  186.     return ret;
  187. }
  188.  
  189. pascal void SafeResolveAlias(FSSpec* fs){
  190.     Boolean isFolder,wasAlias;
  191.     FSSpec temp;
  192.     long gv;
  193.     OSErr oe;
  194.     
  195.     if ((Gestalt(gestaltAliasMgrAttr,&gv)==noErr)&&(gv&gestaltAliasMgrPresent)){
  196.         BlockMoveData((Ptr)fs,(Ptr)(&temp),sizeof(FSSpec));
  197.         
  198.         oe=ResolveAliasFile(fs,true,&isFolder,&wasAlias);
  199.         
  200.         if (oe!=noErr)
  201.             BlockMoveData((Ptr)(&temp),(Ptr)fs,sizeof(FSSpec));
  202.     }
  203. }
  204.  
  205. pascal OSErr GetNthTextFile(CInfoPBRec* cpbp,FSSpecPtr sig,short max_count,short* count){
  206.     OSErr err;
  207.     short index;
  208.     
  209.     *count=0;
  210.     index=1;
  211.     
  212.     do {
  213.         cpbp->hFileInfo.ioNamePtr=sig->name;
  214.         cpbp->hFileInfo.ioDirID=sig->parID;
  215.         cpbp->hFileInfo.ioVRefNum=sig->vRefNum;
  216.         cpbp->hFileInfo.ioFDirIndex=index;
  217.         
  218.         err=PBGetCatInfoSync(cpbp);
  219.         
  220.         index++;
  221.         
  222.         if ((err==noErr)&&(!(cpbp->hFileInfo.ioFlAttrib & 16))&&(cpbp->hFileInfo.ioFlFndrInfo.fdType=='TEXT'))
  223.             (*count)++;
  224.     } while ((err==noErr)&&(*count<max_count));
  225.     
  226.     return err;
  227. }
  228.  
  229. pascal void ChooseRandomSignature(GlobalsHandle globals){
  230.     CInfoPBRec cpb;
  231.     FSSpec sig;
  232.     Handle texth=(Handle)0;
  233.     OSErr err;
  234.     short ref,count;
  235.     long length;
  236.     short junk;
  237.     
  238.     if ((*globals)->current_signature!=(Handle)0){
  239.         DisposeHandle((*globals)->current_signature);
  240.         (*globals)->current_signature=0;
  241.     }
  242.     
  243.     BlockMoveData((Ptr)(*globals)->sig_folder_name,(Ptr)(sig.name),((*globals)->sig_folder_name)[0]+1);
  244.     
  245.     err=FindFolder(kOnSystemDisk,kPreferencesFolderType,kCreateFolder,&(sig.vRefNum),&(sig.parID));
  246.     if (err==noErr){
  247.         SafeResolveAlias(&sig);
  248.         cpb.hFileInfo.ioNamePtr=sig.name;
  249.         cpb.hFileInfo.ioVRefNum=sig.vRefNum;
  250.         cpb.hFileInfo.ioDirID=sig.parID;
  251.         cpb.hFileInfo.ioFDirIndex=0;
  252.         err=PBGetCatInfoSync(&cpb);
  253.     }
  254.     if ((err==noErr)&&(!(cpb.hFileInfo.ioFlAttrib&16)))
  255.         err=dirNFErr;
  256.     
  257.     if (err==noErr){
  258.         sig.parID=cpb.hFileInfo.ioDirID;
  259.         GetNthTextFile(&cpb,&sig,32767,&count);
  260.         if (count==0)
  261.             err=fnfErr;
  262.         else {
  263.             count=(SneakyRandom(globals)%count)+1;
  264.             err=GetNthTextFile(&cpb,&sig,count,&junk);
  265.         }
  266.     }
  267.     
  268.     if (err==noErr){
  269.         SafeResolveAlias(&sig);
  270.         err=HOpen(sig.vRefNum,sig.parID,sig.name,fsRdPerm,&ref);
  271.     }
  272.     
  273.     if (err==noErr){
  274.         err=GetEOF(ref,&length);
  275.         if (err==noErr){
  276.             if (length>4096)
  277.                 length=4096;
  278.             texth=NewHandle(length);
  279.             err=MemError();
  280.         }
  281.         if (err==noErr)
  282.             FSRead(ref,&length,*texth);
  283.         
  284.         FSClose(ref);
  285.     }
  286.     
  287.     if (err!=noErr){
  288.         DisposeHandle(texth);
  289.         texth=(Handle)0;
  290.     }
  291.     
  292.     if (texth==(Handle)0){
  293.         texth=(*globals)->default_signature;
  294.         err=HandToHand(&texth);
  295.         if (err!=noErr)
  296.             texth=(Handle)0;
  297.     }
  298.     
  299.     (*globals)->current_signature=texth;
  300.     
  301. }
  302.  
  303. pascal ICError RSCBegin(GlobalsHandle globals,ICPerm perm){
  304.     ChooseRandomSignature(globals);
  305.     return delegateThisCallErr;
  306. }
  307.  
  308. pascal ICError RSCGetPref(GlobalsHandle globals,StringPtr key,ICAttr* attr,Ptr buf,long* size){
  309.     Str255 tmpstr;
  310.     ICPerm perm;
  311.     long max_size;
  312.     ICError err;
  313.     
  314.     if (IUEqualString(key,kICSignature)==0){
  315.         /*
  316.             This is for compatibility with IC 1.0, which didn't call ICBegin/ICEnd through the target when
  317.             it was done automagically because of a ICGet/SetPref call.  So if there are no permissions then
  318.             we know that we're in about to do an automagic ICBegin so we randomise the signature.
  319.         */
  320.         
  321.         if ((ICCGetPerm((*globals)->delegate,&perm)==noErr)&&(perm==icNoPerm))
  322.             ChooseRandomSignature(globals);
  323.         
  324.         max_size=*size;
  325.         
  326.         if ((*globals)->current_signature==(Handle)0)
  327.             *size=0;
  328.         else
  329.             *size=GetHandleSize((*globals)->current_signature);
  330.         
  331.         err=noErr;
  332.         if ((max_size<0)&&(buf!=(Ptr)0))
  333.             err=paramErr;
  334.         
  335.         if ((err==noErr)&&(buf!=(Ptr)0)){
  336.             if (*size>max_size)
  337.                 err=icTruncatedErr;
  338.             else
  339.                 max_size=*size;
  340.             if (max_size!=0)
  341.                 BlockMoveData((Ptr)(*((*globals)->current_signature)),buf,max_size);
  342.         }
  343.         
  344.         *attr=ICattr_locked_mask + ICattr_volatile_mask;
  345.     } else 
  346.         err=delegateThisCallErr;
  347.     
  348.     return err;
  349. }
  350.  
  351. pascal ICError RSCSetPref(GlobalsHandle globals,StringPtr key,ICAttr* attr,Ptr buf,long* size){
  352.     if (IUEqualString(key,kICSignature)==0)
  353.         return icPermErr;
  354.     return delegateThisCallErr;
  355. }
  356.